#include "zxa_07.h"
//#include "core_debug.h"
#include <stdio.h>
#include <rte_abi.h>

int zxa_07::zxa07_set_cnt(int cnt)
{
    u8 cmdindex = 1;
    u8 buf[12];
    buf[0] = 0xaa;
    buf[1] = 0x55;
    buf[2] = cmdindex;
    buf[3] = 0xc;
    buf[4] = 0;
    buf[5] = 0;
    buf[6] = 0;
    buf[7] = cnt;
    buf[8] = 0;
    buf[9] = 0;
    buf[10] = calc_xor(buf, 10);
    buf[11] = 0 - calc_checsum(buf, 11);
    plc_rte->SerialWrite(serialNo ,buf, 12);
    plc_rte->delay(20);
    return 0;
}

extern "C" void zxa07_thread(const void *arg)
{
    zxa_07 *dev = (zxa_07 *)arg;
    dev->threadloop();
}
void zxa_07::threadloop()
{
    while (1)
    {
        if (zxa07_reciver() < 0)
            errCount++;
        else
        {
            errCount = 0;
            count++;
        }
//        core_debug("%d,count:%d\n",serialNo,count);
    }
}

int zxa_07::zxa07_reciver()
{
    u8 buf[12];
    buf_data_clear(&rx_buf);
    buf[0] = 0xaa;
    buf[1] = 0x55;
    int len = read_head(2, buf, 120000);
    if (len <= 0)
    {
//        core_debug("no data\n");
        status = 100;
        return -1;
    }
    len = read_context(23, 0, 500);
    if (len != 23)
    {
//        core_debug("data len %d\n", len);
        status = 101;
        return -2;
    }
    buf[0] = calc_xor(rx_buf.buf, 25);
    len = read_cmp_context(1, buf, 20);
    if (len <= 0)
    {
//        core_debug("checsum 1 error:%d\n", len);
        status = 102;
        return -1;
    }
    buf[1] = calc_checsum(rx_buf.buf, 26);
    buf[0] = 256 - buf[1];
    len = read_cmp_context(1, buf, 20);
    if (len <= 0)
    {
//        core_debug("checsum 2 error\n");
        status = 103;
        return -1;
    }
    for (len = 0; len < 8; len++)
    {
        u16 val = rx_buf.buf[8 + len * 2] + rx_buf.buf[8 + len * 2 + 1] * 256;
        zxa_val[len] = val;
#if zxa07_nrs > 0
        zxa07_sum[len] -= zxa07_buf[zxa07_save_index][len];
        zxa07_buf[zxa07_save_index][len] = val;
        zxa07_sum[len] += zxa07_buf[zxa07_save_index][len];
#endif
    }
    zxa07_save_index++;
    if (zxa07_save_index >= period)
        zxa07_save_index = 0;
    status = 0;

    return 0;
}

void zxa_07::init(int serialNo)
{
    int len, i;
    this->serialNo = serialNo;
    buf_data_init(&rx_buf, rx, 32);
    for (len = 0; len < 8; len++)
    {
        zxa07_sum[len] = 0;
#if zx07_nrs > 0
        for (i = 0; i < period; i++)
            zxa07_buf[i][len] = 0;
#endif
    }

#ifdef TESTCASE
    zxa07.port = comm_port_win(portname);
#else
    // serial = (HardwareSerial *)pname;
#endif
plc_rte->SerialBegin(serialNo, 9600);
#ifdef RT_THREAD
    rt_thread_t thread = rt_thread_create("zxa07", zxa07_thread, &zxa07, 2048, PRIO_THREAD_DEVICE, RT_TICK_PER_SECOND);
    rt_thread_startup(thread);
#else
    plc_rte->create_thread("zxa07", 256, 0, (void *) &zxa07_thread, this);
#endif
}

#ifdef TESTCASE
#include <embUnit/embUnit.h>
static void setUp(void)
{
    rtthread_startup();
}
static void tearDown(void)
{
    rtthread_exit();
}

static void testGetValue(void *arg)
{
    zxa07_init("COM8");
}

static void test_function()
{
    testGetValue(0);
    rtthread_exit();
}
static void testInit(void)
{

    thread_new(test_function, 0);
    rtthread_run();
}
TestRef tests_zxa07(void);
TestRef tests_zxa07(void)
{
    EMB_UNIT_TESTFIXTURES(fixtures){
        new_TestFixture("testInit", testInit),
        //                        new_TestFixture("testGetValue",testGetValue),
    };
    EMB_UNIT_TESTCALLER(tests_zxa07, "tests_zxa07", setUp, tearDown, fixtures);

    return (TestRef)&tests_zxa07;
}

#endif
